package jp.shts.android.library;

import jp.shts.android.library.utils.AttrUtils;
import jp.shts.android.library.utils.ResUtil;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

public class TriangleLabelView extends Component implements Component.DrawTask {
    private PaintHolder primary = new PaintHolder();
    private PaintHolder secondary = new PaintHolder();
    private Corner corner;
    private Paint trianglePaint;

    private float topPadding;
    private float bottomPadding;
    private float centerPadding;

    private int backGroundColor;

    private int width;
    private int height;
    private static final int DEGREES_LEFT = -45;
    private static final int DEGREES_RIGHT = 45;

    public TriangleLabelView(Context context) {
        this(context, null, null);
    }

    public TriangleLabelView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public TriangleLabelView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(context, attrSet, styleName);
    }

    /* ======================================  private start  ========================================== */
    private void init(Context context, AttrSet attrSet, String styleName) {
        this.topPadding = AttrUtils.getFloatFromAttr(attrSet, "labelTopPadding", dp2px(7, context));
        this.centerPadding = AttrUtils.getFloatFromAttr(attrSet, "labelCenterPadding", dp2px(3, context));
        this.bottomPadding = AttrUtils.getFloatFromAttr(attrSet, "labelBottomPadding", dp2px(3, context));

        this.backGroundColor = AttrUtils.getColorFromAttr(attrSet, "backgroundColor", Color.getIntColor("#66000000"));
        this.primary.color = AttrUtils.getColorFromAttr(attrSet, "primaryTextColor", Color.getIntColor("#FFFFFF"));
        this.secondary.color = AttrUtils.getColorFromAttr(attrSet, "secondaryTextColor", Color.getIntColor("#FFFFFF"));

        this.primary.size = AttrUtils.getDimensionFromAttr(attrSet, "primaryTextSize", dp2px(11, context));
        this.secondary.size = AttrUtils.getDimensionFromAttr(attrSet, "secondaryTextSize", dp2px(8, context));

        final String primaryText = AttrUtils.getStringFromAttr(attrSet, "primaryText", null);
        if (primaryText != null) {
            this.primary.text = primaryText;
        }

        final String secondaryText = AttrUtils.getStringFromAttr(attrSet, "secondaryText", null);
        if (secondaryText != null) {
            this.secondary.text = secondaryText;
        }

        this.primary.style = AttrUtils.getIntFromAttr(attrSet, "primaryTextStyle", 2);
        this.secondary.style = AttrUtils.getIntFromAttr(attrSet, "secondaryTextStyle", 0);

        String cornerStr = AttrUtils.getStringFromAttr(attrSet, "corner", null);
        this.corner = Corner.from(getCornerInt(cornerStr));

        this.primary.initPaint();
        this.secondary.initPaint();

        trianglePaint = new Paint();
        trianglePaint.setAntiAlias(true);
        trianglePaint.setColor(new Color(backGroundColor));

        this.primary.resetStatus();
        this.secondary.resetStatus();
        onMeasure();
        addDrawTask(this);
    }

    private static int dp2px(float dp, Context context) {
        return (int) (context.getResourceManager().getDeviceCapability().screenDensity / 160 * dp);
    }

    private void onMeasure() {
        height = (int) (topPadding + centerPadding + bottomPadding + secondary.height + primary.height);
        width = 2 * height;
        int realHeight = (int) (height * Math.sqrt(2));
        setComponentSize(width, realHeight);
    }

    private int getCornerInt(String cornerStr) {
        if (isEmpty(cornerStr)) {
            return 1;
        }
        if (cornerStr.equals("leftTop")) {
            return 1;
        } else if (cornerStr.equals("rightTop")) {
            return 2;
        } else if (cornerStr.equals("leftBottom")) {
            return 3;
        } else if (cornerStr.equals("rightBottom")) {
            return 4;
        } else {
            return 1;
        }
    }

    private static boolean isEmpty(String input) {
        return input == null || input.length() == 0;
    }

    private void relayout() {
        invalidate();
        postLayout();
    }

    /* ======================================   public start  ========================================== */
    public void setLabelTopPadding(float dp) {
        topPadding = dp2px(dp, getContext());
    }

    public float getLabelTopPadding() {
        return topPadding;
    }

    public void setLabelCenterPadding(float dp) {
        centerPadding = dp2px(dp, getContext());
        relayout();
    }

    public float getLabelCenterPadding() {
        return centerPadding;
    }

    public void setLabelBottomPadding(float dp) {
        bottomPadding = dp2px(dp, getContext());
        relayout();
    }

    public float getLabelBottomPadding() {
        return bottomPadding;
    }

    public void setPrimaryText(String text) {
        primary.text = text;
        primary.resetStatus();
        relayout();
    }

    public void setPrimaryText(int textRes) {
        primary.text = ResUtil.getString(getContext(), textRes);
        primary.resetStatus();
        relayout();
    }

    public String getPrimaryText() {
        return primary.text;
    }

    public void setSecondaryText(String smallText) {
        secondary.text = smallText;
        secondary.resetStatus();
        relayout();
    }

    public void setSecondaryText(int textRes) {
        secondary.text = ResUtil.getString(getContext(), textRes);
        secondary.resetStatus();
        relayout();
    }

    public String getSecondaryText() {
        return secondary.text;
    }

    public void setPrimaryTextColor(int color) {
        primary.color = color;
        primary.initPaint();
        primary.resetStatus();
        relayout();
    }

    public void setPrimaryTextColorResource(int colorResource) {
        primary.color = ResUtil.getColor(getContext(), colorResource);
        primary.initPaint();
        primary.resetStatus();
        relayout();
    }

    public void setSecondaryTextColor(int color) {
        secondary.color = color;
        secondary.initPaint();
        secondary.resetStatus();
        relayout();
    }

    public void setSecondaryTextColorResource(int colorResource) {
        secondary.color = ResUtil.getColor(getContext(), colorResource);
        secondary.initPaint();
        secondary.resetStatus();
        relayout();
    }

    public void setPrimaryTextSize(float sp) {
        primary.size = dp2px(sp, getContext());
        relayout();
    }

    public void setSecondaryTextSize(float sp) {
        secondary.size = dp2px(sp, getContext());
        relayout();
    }

    public float getPrimaryTextSize() {
        return primary.size;
    }

    public float getSecondaryTextSize() {
        return secondary.size;
    }

    public void setTriangleBackgroundColor(int color) {
        backGroundColor = color;
        trianglePaint.setColor(new Color(backGroundColor));
        relayout();
    }

    public void setTriangleBackgroundColorResource(int colorResource) {
        backGroundColor = ResUtil.getColor(getContext(), colorResource);
        trianglePaint.setColor(new Color(backGroundColor));
        relayout();
    }

    public int getTriangleBackGroundColor() {
        return backGroundColor;
    }

    public void setCorner(Corner corner) {
        this.corner = corner;
        relayout();
    }

    public Corner getCorner() {
        return corner;
    }
    /* ======================================   @Override start  ========================================== */
//
//    @Override
//    protected boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
//        super.onEstimateSize(widthEstimateConfig, heightEstimateConfig);
//        height = (int) (topPadding + centerPadding + bottomPadding + secondary.height + primary.height);
//        width = 2 * height;
//        int realHeight = (int) (height * Math.sqrt(2));
//        setEstimatedSize(width, realHeight);
//        return true;
//    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.save();
        // translate
        if (corner.top()) {
            canvas.translate(0, (float) ((height * Math.sqrt(2)) - height));
        }

        // rotate
        if (corner.top()) {
            if (corner.left()) {
                canvas.rotate(DEGREES_LEFT, 0, height);
            } else {
                canvas.rotate(DEGREES_RIGHT, width, height);
            }
        } else {
            if (corner.left()) {
                canvas.rotate(DEGREES_RIGHT, 0, 0);
            } else {
                canvas.rotate(DEGREES_LEFT, width, 0);
            }
        }

        Path path = new Path();
        if (corner.top()) {
            path.moveTo(0, height);
            path.lineTo(width / 2, 0);
            path.lineTo(width, height);
        } else {
            path.moveTo(0, 0);
            path.lineTo(width / 2, height);
            path.lineTo(width, 0);
        }
        path.close();
        canvas.drawPath(path, trianglePaint);

        // draw secondaryText
        if (corner.top()) {
            canvas.drawText(secondary.paint, secondary.text, (width) / 2, topPadding + secondary.height);
            canvas.drawText(
                    primary.paint,
                    primary.text,
                    (width) / 2,
                    (topPadding + secondary.height + centerPadding + primary.height));
        } else {
            canvas.drawText(
                    secondary.paint,
                    secondary.text,
                    (width) / 2,
                    bottomPadding + secondary.height + centerPadding + primary.height);
            canvas.drawText(primary.paint, primary.text, (width) / 2, (bottomPadding + primary.height));
        }
        canvas.restore();
    }

    /* ======================================  PaintHolder start  ========================================== */

    private static class PaintHolder {
        private String text = "";
        private Paint paint;

        private int size;
        private int weight;
        private int height;
        private int color;
        private int style;

        private void initPaint() {
            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(new Color(color));
            paint.setTextAlign(TextAlignment.CENTER);
            paint.setTextSize(size);
            if (style == 1) {
                paint.setFont(Font.SANS_SERIF);
            } else if (style == 2) {
                paint.setFont(Font.DEFAULT_BOLD);
            }
        }

        private void resetStatus() {
            Rect rectText = new Rect();
            rectText = paint.getTextBounds(text);
            weight = rectText.getWidth();
            height = rectText.getHeight();
        }
    }

    /* ======================================  Corner start  ========================================== */

    public enum Corner {
        TOP_LEFT(1),
        TOP_RIGHT(2),
        BOTTOM_LEFT(3),
        BOTTOM_RIGHT(4),
        ;
        private final int type;

        Corner(int type) {
            this.type = type;
        }

        private boolean top() {
            return this == TOP_LEFT || this == TOP_RIGHT;
        }

        private boolean left() {
            return this == TOP_LEFT || this == BOTTOM_LEFT;
        }

        private static Corner from(int type) {
            for (Corner c : values()) {
                if (c.type == type) return c;
            }
            return Corner.TOP_LEFT;
        }
    }
}
